package queue

import (
	"sync"
)

/*
 * 使用互斥锁 多线程安全
 * 使用两个buff 读取时互换指针 批量返回
 */

type mutexQueueData struct {
	slice []interface{}
	index uint32
}

type MutexQueue struct {
	//_padding0 [64]byte
	records0 *mutexQueueData
	//_padding1 [64]byte
	records1 *mutexQueueData
	//_padding2 [64]byte
	lock sync.Mutex
	//_padding3 [64]byte
	size uint32
}

// capaciity must be >= 2

func NewMutexQueue(capaciity uint32) *MutexQueue {
	q := new(MutexQueue)
	q.size = capaciity

	q.records0 = &mutexQueueData{slice: make([]interface{}, q.size)}
	q.records1 = &mutexQueueData{slice: make([]interface{}, q.size)}

	return q
}

func (m *MutexQueue) Write(value interface{}) bool {
	m.lock.Lock()

	nextIndex := m.records0.index + 1
	if nextIndex == m.size {
		m.lock.Unlock()
		return false
	}

	m.records0.slice[m.records0.index] = value
	m.records0.index = nextIndex

	m.lock.Unlock()
	return true
}

func (m *MutexQueue) Read() ([]interface{}, bool) {
	if m.IsEmpty() {
		return nil, false
	}

	m.lock.Lock()
	p0 := m.records0
	m.records0 = m.records1
	m.records0.index = 0

	m.records1 = p0
	m.lock.Unlock()
	return p0.slice[0:p0.index], true
}

func (m *MutexQueue) IsEmpty() bool {
	return m.records0.index == 0
}
